// pages/index/index.js
const {
  processImageToSketch,
  make_sketch
} = require('../../utils/sketch.js');
const {
  ensurePermissions
} = require('../../utils/permission.js');

function isYUVFrame(frame) {
  const {
    width,
    height,
    data
  } = frame;
  return data.length === (width * height * 3 / 2);
}

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

Page({
  data: {
    cameraMode: false,
    devicePosition: 'back',
    originalImg: '',
    sketchImg: '',
    isProcessing: false,
    processingText: '',
    isFromCamera: false,
    sketchParams: {
      blurSize: 3, // 默认为9（奇数）
      threshMin: 0. // 默认为0.9
    }
  },

  async onLoad() {
    // 确保拥有三个权限
    // await ensurePermissions([
    //   'scope.camera',
    //   'scope.writePhotosAlbum'
    // ]);
    // 初始化相机上下文
    this.initCameraContext();
  },

  // 初始化相机上下文
  initCameraContext() {
    this.cameraContext = wx.createCameraContext();
  },

  // 进入相机模式
  enterCameraMode() {
    const that = this;
    wx.getSetting({
      success(res) {
        if (!res.authSetting['scope.camera']) {
          wx.authorize({
            scope: 'scope.camera',
            success() {
              // 开启实时素描或调用相机的函数
              that._doEnterCamera(); // 或者你自己的函数
            },
            fail() {
              wx.showModal({
                title: '需要权限',
                content: '请授权摄像头权限，否则无法使用相机',
                success(res) {
                  if (res.confirm) wx.openSetting();
                }
              });
            }
          });
        } else {
          that._doEnterCamera();
        }
      }
    });
  },
  _doEnterCamera() {
    wx.getSetting({
      success(res) {
        console.log('当前权限状态：', res.authSetting);
      }
    });
    this.setData({
      cameraMode: true,
      originalImg: '',
      sketchImg: ''
    }, () => {
      // 在 enterCameraMode 中添加权限检查
      wx.getSetting({
        success: (res) => {
          if (!res.authSetting['scope.camera']) {
            wx.authorize({
              scope: 'scope.camera',
              success: () => this.initRealtimeSketch(),
              fail: () => this.onCameraError({
                detail: {
                  errMsg: 'camera:fail auth deny'
                }
              })
            });
          } else {
            this.initRealtimeSketch();
          }
        }
      });
      // setTimeout(() => this.initRealtimeSketch(), 300);
    });
  },

  // 实时相机
  initRealtimeSketch() {
    this.setData({
      isFromCamera: true
    })
    if (!this.cameraContext) {
      this.cameraContext = wx.createCameraContext();
    }
    this.timestamp = Date.now()
    this.ondraw = false

    const query = wx.createSelectorQuery();
    query.select('#previewCanvas')
      .fields({
        node: true,
        size: true
      })
      .exec((res) => {
        if (!res[0] || !res[0].node) {
          console.error('Canvas not found');
          wx.showToast({
            title: '画布初始化失败',
            icon: 'none'
          });
          return;
        }
        const systemInfo = wx.getSystemInfoSync();
        const dpr = systemInfo.pixelRatio;
        const screenWidth = systemInfo.windowWidth;
        const screenHeight = systemInfo.windowHeight;
        // canvas 节点对象
        this.canvas = res[0].node;
        this.ctx = this.canvas.getContext('2d');
        // 设置 canvas 分辨率（物理像素）
        this.canvas.width = screenWidth * dpr;
        this.canvas.height = screenHeight * dpr;
        // 设置缩放
        this.ctx.scale(dpr, dpr);
        // 画红色测试块
        // this.ctx.fillStyle = 'red';
        // this.ctx.fillRect(0, 0, screenWidth, screenHeight);
        // console.log('canvas pixel size:', this.canvas.width, this.canvas.height);

        // 启动帧监听
        this.frameListener = this.cameraContext.onCameraFrame(async (frame) => {
          // console.log(1111111111111)
          if (!frame || !frame.data || !this.ctx) return;
          // 降低帧率
          if (Date.now() - this.timestamp < 250) return;
          this.timestamp = Date.now()
          await sleep(20)
          const od = this.ondraw
          this.ondraw = true
          await sleep(20)
          if (od) return;
          this.ondraw = false
          // console.log(22222222222222)
          try {
            // 创建红色纯色图模拟“算法结果”
            const width = this.canvas.width;
            const height = this.canvas.height;
            if (!this.cachedImageData || this.cachedImageData.width !== width || this.cachedImageData.height !== height) {
              this.cachedImageData = this.ctx.createImageData(width, height);
            }
            const imageData = this.cachedImageData;
            const frameData = new Uint8Array(frame.data);
            const {
              blurSize,
              threshMin
            } = this.data.sketchParams;
            // console.log(11111111111)
            make_sketch(frameData, frame.width, frame.height, imageData.data, width, height, 3, threshMin)
            // console.log(threshMin)

            // 画布绘制
            this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
            this.ctx.putImageData(imageData, 0, 0);
          } catch (e) {
            console.error('Frame processing error:', e);
          }
        });

        this.frameListener.start();
      });
  },

  onUnload() {
    if (this.frameListener) {
      this.frameListener.stop();
      this.frameListener = null;
    }
  },

  // 从相册选择图片
  chooseFromAlbum() {
    this.setData({
      isFromCamera: false
    })
    wx.chooseImage({
      count: 1,
      sizeType: ['compressed'],
      sourceType: ['album'],
      success: async (res) => {
        if (res.tempFilePaths.length === 0) return;

        this.setData({
          originalImg: res.tempFilePaths[0],
          sketchImg: '',
          isProcessing: true,
          processingText: '正在处理...'
        });

        try {
          const {
            blurSize,
            threshMin
          } = this.data.sketchParams;
          const sketchPath = await processImageToSketch(res.tempFilePaths[0], blurSize, threshMin);
          this.setData({
            sketchImg: sketchPath
          });
        } catch (error) {
          console.error('素描处理失败:', error);
          wx.showToast({
            title: '处理失败',
            icon: 'none'
          });
        } finally {
          this.setData({
            isProcessing: false
          });
        }
      }
    });
  },

  // 切换摄像头
  switchCamera() {
    this.setData({
      devicePosition: this.data.devicePosition === 'back' ? 'front' : 'back'
    });
  },

  // 相机错误处理
  onCameraError(e) {
    console.error('相机错误:', e.detail);
    wx.showToast({
      title: `相机错误: ${e.detail.errMsg}`,
      icon: 'none'
    });
  },

  // 修改拍照函数
  capturePhoto() {
    if (!this.cameraContext) {
      this.cameraContext = wx.createCameraContext();
    }

    // 显示加载提示
    wx.showLoading({
      title: '拍照中...',
      mask: true
    });

    this.cameraContext.takePhoto({
      quality: 'high',
      success: async (res) => {
        wx.hideLoading();
        if (!res.tempImagePath) {
          wx.showToast({
            title: '未获取到照片',
            icon: 'none'
          });
          return;
        }

        // 确保退出相机模式
        this.exitCameraMode();

        this.setData({
          originalImg: res.tempImagePath,
          sketchImg: '',
          isProcessing: true,
          processingText: '生成素描中...'
        });

        try {
          const {
            threshMin,
            blurSize
          } = this.data.sketchParams;
          const sketchPath = await processImageToSketch(res.tempImagePath, 3, threshMin);
          this.setData({
            sketchImg: sketchPath,
            sketchParams: {
              blurSize: 3,
              threshMin: threshMin
            }
          });
        } catch (error) {
          console.error('素描处理失败:', error);
          wx.showToast({
            title: '处理失败: ' + error.message,
            icon: 'none'
          });
        } finally {
          this.setData({
            isProcessing: false
          });
        }
      },
      fail: (err) => {
        wx.hideLoading();
        console.error('拍照失败:', err);
        wx.showToast({
          title: '拍照失败: ' + err.errMsg,
          icon: 'none'
        });
      }
    });
  },

  // 修改退出相机模式函数
  exitCameraMode() {
    if (this.frameListener) {
      this.frameListener.stop();
      this.frameListener = null;
    }
    this.setData({
      cameraMode: false
    });
  },

  // 添加全局错误处理
  onCameraError(e) {
    console.error('相机错误:', e.detail);
    let errorMsg = '相机错误';

    switch (e.detail.errMsg) {
      case 'camera:fail auth deny':
        errorMsg = '请授予相机权限';
        break;
      case 'camera:fail system busy':
        errorMsg = '相机被占用，请重试';
        break;
      case 'camera:fail no camera':
        errorMsg = '未检测到可用相机';
        break;
      default:
        errorMsg = `相机错误: ${e.detail.errMsg}`;
    }

    wx.showToast({
      title: errorMsg,
      icon: 'none'
    });
    this.exitCameraMode();
  },

  // 保存函数
  saveSketchImage() {
    const that = this;
    // ✅ 1. 主动检查保存权限
    wx.getSetting({
      success(res) {
        if (!res.authSetting['scope.writePhotosAlbum']) {
          wx.authorize({
            scope: 'scope.writePhotosAlbum',
            success() {
              that._doSaveImage(); // 授权成功后执行保存逻辑
            },
            fail() {
              wx.showModal({
                title: '需要权限',
                content: '请授权保存图片到相册，否则无法保存',
                success(res) {
                  if (res.confirm) wx.openSetting();
                }
              });
            }
          });
        } else {
          that._doSaveImage(); // 已授权，直接保存
        }
      }
    });
  },

  // ✅ 把原始保存逻辑抽出来作为 _doSaveImage
  _doSaveImage() {
    const that = this;
    const origin_url = this.data.originalImg
    const url = this.data.sketchImg;
    if (!url) {
      wx.showToast({
        title: '没有图片可保存',
        icon: 'none'
      });
      return;
    }

    if (this.data.isFromCamera) {
      wx.getImageInfo({
        src: origin_url,
        success(res) {
          wx.saveImageToPhotosAlbum({
            filePath: res.path,
            success() {
              wx.showToast({
                title: '保存成功',
                icon: 'success'
              });
            },
            fail(err) {
              if (err.errMsg.includes('auth')) {
                wx.showModal({
                  title: '需要权限',
                  content: '请允许保存图片到相册',
                  success(res) {
                    if (res.confirm) {
                      wx.openSetting();
                    }
                  }
                });
              } else {
                wx.showToast({
                  title: '保存失败',
                  icon: 'none'
                });
              }
            }
          });
        },
        fail() {
          wx.showToast({
            title: '获取图片失败',
            icon: 'none'
          });
        }
      });
    }

    // 下载临时文件（确保是本地路径）
    wx.getImageInfo({
      src: url,
      success(res) {
        wx.saveImageToPhotosAlbum({
          filePath: res.path,
          success() {
            wx.showToast({
              title: '保存成功',
              icon: 'success'
            });
          },
          fail(err) {
            if (err.errMsg.includes('auth')) {
              wx.showModal({
                title: '需要权限',
                content: '请允许保存图片到相册',
                success(res) {
                  if (res.confirm) {
                    wx.openSetting();
                  }
                }
              });
            } else {
              wx.showToast({
                title: '保存失败',
                icon: 'none'
              });
            }
          }
        });
      },
      fail() {
        wx.showToast({
          title: '获取图片失败',
          icon: 'none'
        });
      }
    });

  },

  onThreshMinChange(e) {
    const value = e.detail.value / 100; // 还原为 0.00 ~ 0.99
    this.setData({
      'sketchParams.threshMin': value
    }, this.updateSketch);
  },

  onBlurSizeChange(e) {
    const value = parseInt(e.detail.value);
    // 保证是奇数
    const oddValue = value % 2 === 0 ? value + 1 : value;
    this.setData({
      'sketchParams.blurSize': oddValue
    }, this.updateSketch);
  },

  updateSketch() {
    const originalImg = this.data.originalImg;
    const {
      blurSize,
      threshMin
    } = this.data.sketchParams;

    if (!originalImg) return;

    this.setData({
      isProcessing: true
    });

    processImageToSketch(originalImg, blurSize, threshMin)
      .then(path => {
        this.setData({
          sketchImg: path
        });
      })
      .catch(err => {
        wx.showToast({
          title: '更新失败',
          icon: 'none'
        });
        console.error('Sketch update error:', err);
      })
      .finally(() => {
        this.setData({
          isProcessing: false
        });
      });
  }

});